﻿using Guild_Wars_2.Common;
using Guild_Wars_2.Data;
using Guild_Wars_2.DataModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using Windows.Data.Json;
using Windows.Data.Xml.Dom;
using Windows.Storage;
using Windows.UI.Xaml.Data;

namespace Guild_Wars_2.APITools
{
    class API
    {
        // Get the data Object from the Guild Wars 2 API
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="apiUri">API URI to be passed</param>
        /// <returns>JsonObject with retrieved data</returns>
        private static async Task<JsonObject> getAPIDataObject(Uri apiUri)
        {
            var client = new HttpClient();
            var response = await client.GetAsync(apiUri);
            var result = await response.Content.ReadAsStringAsync();
            return JsonObject.Parse(result);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="apiUri">API URI to be passed</param>
        /// <returns>JsonArray with retrieved data</returns>
        private static async Task<JsonArray> getAPIDataArray(Uri apiUri)
        {
            var client = new HttpClient();
            var response = await client.GetAsync(apiUri);
            var result = await response.Content.ReadAsStringAsync();
            return JsonArray.Parse(result);
        }
        
        public static async Task<string> LoadEventsFromAPI(string world_id)
        {
            JsonObject eventsForWorld = await getAPIDataObject(new Uri(Constants.API_BASE + Constants.EVENTS_FOR_WORLD + world_id));

            JsonArray events;
            IJsonValue eventsVal;

            var eventsKey = eventsForWorld.Keys.First();
           
            if (eventsForWorld.TryGetValue(eventsKey, out eventsVal))
                if (eventsVal.ValueType != JsonValueType.Null)
                {
                    events = eventsVal.GetArray();

                    foreach (var item in events)
                    {
                        var obj = item.GetObject();

                        double map_id = 0;
                        String event_id = "";
                        String state = "";

                        foreach (var key in obj.Keys)
                        {
                            IJsonValue val;
                            if (!obj.TryGetValue(key, out val))
                                continue;

                            if (val.ValueType == JsonValueType.Null)
                                continue;

                            switch (key)
                            {
                                case "map_id":
                                    map_id = val.GetNumber();
                                    break;
                                case "event_id":
                                    event_id = val.GetString();
                                    break;
                                case "state":
                                    state = val.GetString();
                                    break;
                            }
                        }

                        foreach (GW2Events checkItem in GW2Events.EventsToWatch)
                        {                            
                            if (checkItem.Event_Id == event_id)
                            {
                                checkItem.Event_State = state;
                                break;
                            }
                        }

                    }
                }

            return "Hoi";
        }

        public static async Task<XmlDocument> LoadNamesFromAPI(string APISelection)
        {
            var jsonNames = await getAPIDataArray(new Uri(Constants.API_BASE + APISelection + Constants.JSON_NAMES));

            XmlDocument APIXMLDocument = new XmlDocument();
            APIXMLDocument.LoadXml(Constants.XML_BASE_FILE);

            foreach (var item in jsonNames)
            {
                var obj = item.GetObject();

                String id = "";
                String name = "";

                foreach (var key in obj.Keys)
                {
                    IJsonValue val;
                    if (!obj.TryGetValue(key, out val))
                        continue;

                    if (val.ValueType == JsonValueType.Null)
                        continue;

                    switch (key)
                    {
                        case "id":
                            id = val.GetString();
                            break;
                        case "name":
                            name = val.GetString();
                            break;
                    }
                }

                // Create a new root node
                XmlElement root = APIXMLDocument.DocumentElement;
                XmlElement newElem = APIXMLDocument.CreateElement(APISelection);
                root.AppendChild(newElem);

                // Create an element node for id
                XmlElement newElemDetail = APIXMLDocument.CreateElement("id");
                newElemDetail.InnerText = id;
                newElem.AppendChild(newElemDetail);

                // Create an element node for name
                newElemDetail = APIXMLDocument.CreateElement("name");
                newElemDetail.InnerText = name;
                newElem.AppendChild(newElemDetail);
            }
            int counterLive = APIXMLDocument.ChildNodes[1].ChildNodes.Count();
            int counterOffline = 0;

            switch (APISelection)
            {
                case Constants.WORLDS :
                    counterOffline = GW2DataSource.NrOfServers();
                    break;
                case Constants.EVENTS :
                    counterOffline = GW2DataSource.NrOfEvents();
                    break;
                case Constants.MAPS:
                    counterOffline = GW2DataSource.NrOfMaps();
                    break;
            }            

            if (
                ((counterLive - counterOffline) > 0) ||
                (((counterLive - counterOffline) < 0) && ((counterLive - counterOffline) > -5))
               )
            {
                // More servers are reported live by ArenaNet
                // or
                // There are online a few less servers then based upon the default settings from the app

                // Update local data with live data from ArenaNet
                StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(APISelection + Constants.XML_FILE_NAME, CreationCollisionOption.ReplaceExisting);
                await APIXMLDocument.SaveToFileAsync(file);
            }
            // else do nothing            

            return APIXMLDocument;
        }

        public static async Task<string> loadColors()
        {
            JsonObject jsonColors = await getAPIDataObject(new Uri(Constants.API_BASE + "colors.json"));

            JsonObject dyes = jsonColors.GetNamedObject("colors");
            IJsonValue colorVal;
            //"colors": {
            //  "126": {
            //    "name": "Hot Pink",
            //    "base_rgb": [ 128, 26, 26 ],
            //    "cloth": {
            //      "brightness": 14,
            //      "contrast": 1.21094,
            //      "hue": 340,
            //      "saturation": 0.820313,
            //      "lightness": 1.44531,
            //      "rgb": [ 169, 54, 94 ]
            //    },
             var colorKey = dyes.Keys.First();
            // var ask = dyes.Keys.
            if (dyes.TryGetValue(colorKey, out colorVal))
            {
                if (colorVal.ValueType != JsonValueType.Null)
                {
                    dyes = colorVal.GetObject();
                    
                      foreach (var key in dyes.Keys)
                        {
                            IJsonValue val;
                            if (!dyes.TryGetValue(key, out val))
                                continue;

                            if (val.ValueType == JsonValueType.Null)
                                continue;

                        //IJsonValue colorValue = Key;
                        string name = "";
                        string material = "";
                        string[] rgb = new string[3];
                        string base_rgb;
    
                      
                            switch (key)
                            {
                                case "name":
                                   // name = val.GetString();
                                    break;
                                case "base_rgb":
                                    //base_rgb = val.GetArray();
                                    break;

                                case "cloth":
                                case "metal":
                                case "leather":
                                   //material = val.ToString();
                                    break;
                            }
                        }

                    }
                
            }
            return "a";
           // return jsonColors.Stringify();
        }
        
        public static async Task<double> loadBuildNr()
        {
            JsonObject gw2_build_id_obj = await getAPIDataObject(new Uri(Constants.API_BASE + Constants.BUILD));

            IJsonValue buildIdVal;
            double build_id = 0;

            var build_obj = gw2_build_id_obj.Keys.First();

            if (gw2_build_id_obj.TryGetValue(build_obj, out buildIdVal))
                if (buildIdVal.ValueType != JsonValueType.Null)
                    build_id = buildIdVal.GetNumber();

            return build_id;
        }

    }
}
